#include<iostream>
#include<sys/types.h>
#include<sys/wait.h>
#include<assert.h>
#include<cstring>
#include<unistd.h>
#include<cstdio>

#define MAX 1024

using namespace std;

//管道4种情况
//  1.正常情况：管道中没有数据，读端必须等待，直到有人写数据
//  2.正常情况：管道数据被写满，写端必须等待，直到有人读数据
//  3.异常情况：写端关闭，读端一直读取，直到获取read返回值为0
//  4.异常情况：读端关闭，写端一直写入，写端进程会被OS直接杀掉

//匿名管道fd[0]:读端，fd[1]:写端
int main()
{
    //创建匿名管道
    int fd[2]={0};
    if(pipe(fd)<0){
        perror("pipe");
        return 1;
    }

    //创建子进程
    pid_t id=fork();
    if(id<0){
        perror("fork");
        return 1;
    }
    if(id==0)
    {
        //child写入
        close(fd[0]);
        int cnt=0;
        while(1){
            char msg[MAX];
            snprintf(msg,sizeof(msg),"i am child,pid:%d,cnt:%d",getpid(),cnt++);
            write(fd[1],msg,strlen(msg));
            sleep(1);
        }
        close(fd[1]);
        exit(0);
    }
    //father
    close(fd[1]);

    char msg[MAX];
    while(1){
        ssize_t s=read(fd[0],msg,sizeof(msg)-1);
        if(s>0){
            msg[s]=0;
            cout<<getpid()<<","<<"child say"<<msg<<"to me"<<endl;
        }
        else if(s==0){
            cout<<"child quit"<<endl;
            break;
        }
        else{
          cout<<"read error"<<endl;
          break;
        }
    }

    close(fd[0]);
    waitpid(id,NULL,0);
    return 0;
}
